package com.zhuhjay.web.controller;

import com.zhuhjay.common.annotation.ApiLimit;
import com.zhuhjay.common.annotation.AuthToken;
import com.zhuhjay.common.annotation.OperationLog;
import com.zhuhjay.common.domain.ResponseJson;
import com.zhuhjay.common.domain.controller.BaseController;
import com.zhuhjay.common.enums.HttpCode;
import com.zhuhjay.common.utils.JwtUtils;
import com.zhuhjay.system.domain.entity.User;
import com.zhuhjay.system.domain.vo.*;
import com.zhuhjay.system.service.IUserService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import javax.validation.constraints.Min;

import static com.zhuhjay.common.domain.ResponseJson.error;
import static com.zhuhjay.common.domain.ResponseJson.success;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author zhuhjay
 * @since 2022-03-20
 */
@Validated
@RestController
@RequestMapping("/system/user")
public class UserController extends BaseController {

    private final IUserService userService;
    private final BCryptPasswordEncoder passwordEncoder;

    public UserController(IUserService userService,
                          BCryptPasswordEncoder passwordEncoder){
        this.userService = userService;
        this.passwordEncoder = passwordEncoder;
    }

    @ApiLimit
    @PostMapping("/login")
    @OperationLog(operaDesc = "登录", hasResult = false)
    public ResponseJson login(@Valid @RequestBody UserLogin userForm){
        sendBodyToSession(userForm);
        User userInfo = userService.getUserByUsername(userForm.getUsername());
        if( userInfo == null ){
            return error("用户名{" + userForm.getUsername() + "}不存在");
        }
        // 校验密码是否相同
        boolean matches = passwordEncoder
                .matches(userForm.getPassword(), userInfo.getPassword());
        if( matches ){
            String token = JwtUtils.generateToken(userForm.getUsername());
            // 修改用户的登录信息
            userService.setLoginInfo(userInfo.getId());
            return success("登录成功").appendData("token", token);
        }else{
            return error("登录密码错误");
        }
    }

    @ApiLimit
    @AuthToken
    @PostMapping()
    @OperationLog(operaDesc = "创建新用户")
    public ResponseJson createUser(@Validated @RequestBody RegisterUser registerUser){
        sendBodyToSession(registerUser);
        userService.saveUser(registerUser);
        return success();
    }

    @ApiLimit
    @AuthToken
    @GetMapping()
    @OperationLog(operaDesc = "获取个人信息", hasResult = false)
    public ResponseJson getUserInfo(Integer id){
        return success()
                .appendData("userInfo", userService.getUserInfoById(id));
    }

    @ApiLimit
    @AuthToken
    @PostMapping("/avatar")
    @OperationLog(operaDesc = "修改个人头像")
    public ResponseJson setUserAvatar(Integer id, @RequestPart("avatar") MultipartFile file){
        if( file.isEmpty() ){
            return error("上传的文件不能为空");
        }
        String avatarPath = userService.setUserAvatarById(id, file);
        return success().appendData("avatar", avatarPath);
    }

    @ApiLimit
    @AuthToken
    @PatchMapping()
    @OperationLog(operaDesc = "修改个人信息")
    public ResponseJson setUserInfo(Integer id, @Validated @RequestBody UserInfo userInfo){
        sendBodyToSession(userInfo);
        userService.setUserInfoById(id, userInfo);
        return success(HttpCode.UPDATE_SUCCESS);
    }

    @ApiLimit
    @AuthToken
    @PatchMapping("/password")
    @OperationLog(operaDesc = "修改密码")
    public ResponseJson setPassword(Integer id, @Validated @RequestBody Password password){
        sendBodyToSession(password);
        User userInfo = userService.getById(id);
        // 校验密码是否相同
        boolean matches = passwordEncoder
                .matches(password.getPassword(), userInfo.getPassword());
        if( !matches ){
            return error("密码错误");
        }
        if( !password.getNewPassword().equals(password.getTruePassword()) ){
            return error("两次密码输入不一致");
        }
        // 将确认的密码传入进行密码修改
        userService.setPassword(id, password.getTruePassword());
        return success(HttpCode.UPDATE_SUCCESS);
    }

    @ApiLimit
    @AuthToken
    @GetMapping("/list")
    @OperationLog(operaDesc = "获取用户列表", hasResult = false)
    public ResponseJson getUserList(Integer id,
                        @RequestParam(name = "pageNum", defaultValue = "1")
                        @Min(1) Integer pageNum,
                        @RequestParam(name = "pageSize", defaultValue = "10")
                        @Min(1) Integer pageSize){
        sendBodyToSession(new PageInfo(pageNum, pageSize, null));
        return success()
                .appendData("userListPage", userService.getUserList(id, pageNum, pageSize));
    }

}
